/*
 * @Author: your name
 * @Date: 2021-09-02 18:13:12
 * @LastEditTime: 2021-09-02 19:06:30
 * @LastEditors: your name
 * @Description: In User Settings Edit
 * @FilePath: /03 Stacks/stack.c
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "stack.h"

bool CreateStack(Stack *stack, int size) {
  if(size < 1)
    return false;
  stack->values = (double*)malloc(sizeof(double) * size);
  // The stack is initialized to be empty:
  stack->top = -1;
  stack->maxTop = size - 1;
  return true;
}

bool IsEmpty(Stack *stack) {
  // The stack is empty when the stack's top index is equal to -1:
  return stack->top == -1;
}

bool IsFull(Stack *stack) {
  // The stack is full when the stack's top index is equal to the last index:
  return stack->top == stack->maxTop;
}

bool Top(Stack *stack, double *x) {
  if(IsEmpty(stack))
    return false;
  // Pass the value of the top element to x:
  *x = stack->values[stack->top];
  return true;
}

bool Push(Stack *stack, double x) {
  if(IsFull(stack))
    return false;
  // Add x to the stack.  top must be increased before we use it as an index:
  stack->values[++stack->top] = x;
  return true;
}

bool Pop(Stack *stack, double *x) {
  if(IsEmpty(stack))
    return false;
  // Pass the value of the top element to x.
  // top must be decreased after we use it as an index:
  *x = stack->values[stack->top--];
  return true;
}

void DisplayStack(Stack *stack) {
  printf("top --> ");
  for(int i = stack->top; i > -1; i--)
    printf("|  %9f  |\n        ", stack->values[i]);
  printf("+-------------+\n");
}

void DestroyStack(Stack *stack) {
  free(stack->values);
  // Setting the values pointer to NULL is a good practice to prevent
  // illegal memory access to the array's content after the array has been
  // freed.
  stack->values = NULL;
  stack->top = -1;
  stack->maxTop = -1;
}


int main(void) {
  Stack stack;
  double val;
  CreateStack(&stack, 5);
  Push(&stack, 5.0);
  Push(&stack, 6.5);
  Push(&stack, -3.0);
  Push(&stack, -8.0);
  DisplayStack(&stack);
  if(Top(&stack, &val))
    printf("Top: %f\n", val);
  Pop(&stack, &val);
  if(Top(&stack, &val))
    printf("Top: %f\n", val);
  while(!IsEmpty(&stack))
    Pop(&stack, &val);
  DisplayStack(&stack);
  DestroyStack(&stack);
  return 0;
}
